/**
 * Copyright (C),2011-2012,北京国电通网络技术有限公司.
 * FileName:	main.cpp
 * Author:		LiuHaifeng
 * Version:		V0.1
 * Date:		2011-11-15
 * Description	In this file, we do some initialization necessary, start other two threads, protocol switch, sending command and so on.
 */
/**
 * History:
 * 		Author		date		Version		Description
 */

#include "../global/global.h"
#include "downLoop.h"
#include "protocol.h"

extern struct StDownTask g_downTask;
//extern struct StUpTask g_upTask;
extern struct StOther g_other;
extern struct StLED g_LED;
extern int setLed_ON;
extern int setLed_OFF;

//#define DEBUG_SERIAL_ONLY

#ifdef DEBUG_SERIAL_ONLY
#include "../serial/serial.h"

#define DEBUG_TEST_STRING "68a0a1a2a3a4a568010243C3cs16"
extern struct StSerialFD g_serialFD;
extern struct StDataTransmit g_dataTrans;
int main(int argc,char *argv[])
{

	//globalInit();
	
	g_serialFD.st_serial0=-1;
	
	printf("begin open serial port 0.\n");
	
	//g_serialFD.st_serial0=openPort(1,B9600,8,1,'N');
	g_serialFD.st_serial0=openPort(1,B115200,8,1,'N');

	if(-1==g_serialFD.st_serial0)
	{
		ERROROUT("open ttyS1 failed!");
		return -1;
	}

	printf(" open serial port 0 successfully.\n");

    memset(g_dataTrans.st_sendSerial,0,SENDSERIAL_NUM);
	
	//strcpy((char *)g_dataTrans.st_sendSerial,(char *)DEBUG_TEST_STRING);
	g_dataTrans.st_sendSerial[0] = 0x68;
	g_dataTrans.st_sendSerial[1] = 0x99;
	g_dataTrans.st_sendSerial[2] = 0x99;
	g_dataTrans.st_sendSerial[3] = 0x99;
	g_dataTrans.st_sendSerial[4] = 0x99;
	g_dataTrans.st_sendSerial[5] = 0x99;
	g_dataTrans.st_sendSerial[6] = 0x99;


	g_dataTrans.st_sendSerial[7] = 0x68;
	g_dataTrans.st_sendSerial[8] = 0xD;
	g_dataTrans.st_sendSerial[9] = 0x0;
	g_dataTrans.st_sendSerial[10] = 0x73;
	g_dataTrans.st_sendSerial[11] = 0x16;

	printf(" begin write data to serial port 0 .\n");

	//sendSerial(strlen(DEBUG_TEST_STRING));
	sendSerial(12);

	printf(" write data to serial port 0 successfully.\n");


	return 0;
}
#else

int main(int argc, char * argv[])
{
	PRINTOUT("%s","in main()");
	///initialization
	if(-1==globalInit())
	{
		ERROROUT("globalInit error.");
		return -1;
	}
	int l_position=NO_MORE;
	clearFlag();
	while(1)
	{
		///down-stream dispose
		sem_wait(&g_downTask.st_task.st_sem);
		if(-1==(l_position=getElem(g_downTask.st_task)))
		{
			sem_post(&g_downTask.st_task.st_sem);
			myDelay(10);				///???bug???sleep 10 ms
		}
		else
		{
			sem_post(&g_downTask.st_task.st_sem);
			if(prio_retry==g_downTask.st_command[l_position].priority)
			{
				if(com_waitRetry==g_downTask.st_command[l_position].needRetry)
				{
					int l_newPos;
					sem_wait(&g_downTask.st_emtpy.st_sem);
					l_newPos=getElem(g_downTask.st_emtpy);
					sem_post(&g_downTask.st_emtpy.st_sem);
					if(-1==l_newPos)
					{
						myDelay(10);	///???bug???sleep 10 ms
						continue;
					}
					memcpy(&g_downTask.st_command[l_newPos],&g_downTask.st_command[l_position],sizeof(struct StControlCmd));
					g_downTask.st_command[l_newPos].needRetry=com_havRetry;
					g_downTask.st_command[l_newPos].retryTime++;
					sem_wait(&g_downTask.st_task.st_sem);
					insertElem(g_downTask.st_task,l_newPos);
					sem_post(&g_downTask.st_task.st_sem);
				}
				else if(com_havRetry==g_downTask.st_command[l_position].needRetry)
				{

					if(g_downTask.st_command[l_position].removeNum++ > REMOVE_NUM)
					{
						sem_wait(&g_downTask.st_emtpy.st_sem);
						insertElem(g_downTask.st_emtpy,l_position);
						sem_post(&g_downTask.st_emtpy.st_sem);
					}
					else
					{
						sem_wait(&g_downTask.st_task.st_sem);
						insertElem(g_downTask.st_task,l_position);
						sem_post(&g_downTask.st_task.st_sem);
					}
					myDelay(10);		///???bug???sleep 10 ms
					continue;
				}
			}

			PRINTOUT("%s","dispose 'g_downTask.st_task'.");
			if(-1==commandDispose(l_position))
			{
				ERROROUT("commandDispose() failed!");
				///return;		///just ignore
			}
			sem_wait(&g_downTask.st_emtpy.st_sem);
			insertElem(g_downTask.st_emtpy,l_position);
			sem_post(&g_downTask.st_emtpy.st_sem);
		}
		myDelay(10);		///???bug???sleep 10 ms
	}

	///unmap shared memory.
	munmap(g_other.st_shmADDR,SHARESIZE);
	//system("ipcs -m");
	close(g_other.st_shmFD);

	///turn off the file descriptor of LED
#ifndef DEBUG_PC
	#ifdef FREESCALE
		write(g_LED.st_status,&setLed_OFF,1);
	#else
		ioctl(g_LED.st_status, SET_LED_OFF, NULL);
	#endif
	close(g_LED.st_status);
	close(g_LED.st_mod2);
	close(g_LED.st_mod3);
#endif

	return 0;
}


#endif


